package com.zmj.sy.mom.srv.aps.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.PartPallet;
import com.zmj.sy.mom.srv.aps.bean.entity.mes.WorkDetailTask;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsWorkDetail;
import com.zmj.sy.mom.srv.aps.bean.entity.order.OrderPart;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Group;
import com.zmj.sy.mom.srv.aps.bean.entity.resource.Phase;
import com.zmj.sy.mom.srv.aps.bean.entity.workQueue.MesWorkDetail;
import com.zmj.sy.mom.srv.aps.bean.vo.apsworkdetail.*;
import com.zmj.sy.mom.srv.aps.bean.vo.base.*;
import com.zmj.sy.mom.srv.aps.config.ProjectConfig;
import com.zmj.sy.mom.srv.aps.feign.MbdFeign;
import com.zmj.sy.mom.srv.aps.mapper.*;
import com.zmj.sy.mom.srv.aps.utils.DateUtils;
import com.zmj.sy.mom.srv.aps.utils.SyExceptionUtils;
import com.zmj.sy.mom.srv.aps.utils.SySecurityUtils;
import com.zmj.sy.mom.srv.mbd.api.bean.entity.AssemblyInfo;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.redisson.api.RedissonClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class ApsWorkDetailService {

    private static final Logger log = LoggerFactory.getLogger(ApsWorkDetailService.class);
    private final ApsWorkDetailMapper apsWorkDetailMapper;
    private final WorkQueueMapper workQueueMapper;
    private final MesWorkDetailMapper mesWorkDetailMapper;
    private final WorkDetailTaskMapper workDetailTaskMapper;
    private final PhaseGroupMapper phaseGroupMapper;
    private final PartPalletMapper partPalletMapper;
    private final GroupMapper groupMapper;
    private final PhaseMapper phaseMapper;
    private final AdoWorkDetailMapper adoWorkDetailMapper;
    private final RedissonClient getRedisson;
    private final OrderPartMapper orderPartMapper;
    private final ProjectConfig projectConfig;
    private final MbdFeign mbdFeign;

    public BaseListResVo<ApsWorkDetailListResVo> list(BaseIdReqVo reqVo) {

        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        wrapper.eq("wd.aps_work_order_id", reqVo.getId());
        wrapper.eq("wd.deleted", 0);

        wrapper.orderByAsc("wd.phase_seq", "wd.plan_start_date_time");
//        GROUP BY wo.work_order_code,wd.phase_name,wd.phase_code,wd.finish_count,wd.work_time,wd.station_group_id,wd.group_code,s.my_code,wd.station_id,wd.plan_start_date_time,wd.plan_end_date_time,s.work_ability,s.productivity,wd.total_work_time,wd.enter_time,wd.out_time,wd.chang_time,sws.NAME,sws.shift_type_id,wd.phase_seq
        List<ApsWorkDetailListResVo> apsWorkDetailListResVos = apsWorkDetailMapper.selectByWorkOrderId(wrapper);
//        Map<String, ApsWorkDetailListResVo> collect = apsWorkDetails.stream().collect(Collectors.toMap(ApsWorkDetailListResVo::getPhaseCode, Function.identity(), (e1, e2) -> {
//            e1.setTotalCount(e1.getTotalCount().add(e2.getTotalCount()));
//            return e1;
//        }));
//        List<ApsWorkDetailListResVo> apsWorkDetailListResVos = new ArrayList<>(collect.values());
        apsWorkDetailListResVos.sort(Comparator.comparing(ApsWorkDetailListResVo::getPhaseSeq).thenComparing(ApsWorkDetailListResVo::getPlanEndDateTime));

        List<Phase> phaseList = phaseMapper.lambdaQuery().isNotNull(Phase::getMyCode).isNotNull(Phase::getName).list();
        Map<String, Phase> phaseMap = phaseList.stream().collect(Collectors.toMap(Phase::getMyCode, e -> e));

        for (ApsWorkDetailListResVo apsWorkDetailListResVo : apsWorkDetailListResVos) {
            apsWorkDetailListResVo.setTotalWorkTime(apsWorkDetailListResVo.getTotalWorkTime().setScale(2, RoundingMode.UP));
            apsWorkDetailListResVo.setWorkTime(apsWorkDetailListResVo.getWorkTime().setScale(2, RoundingMode.UP));

            Phase phase = phaseMap.get(apsWorkDetailListResVo.getPhaseCode().replaceFirst("\\d+", ""));
            if(phase != null){
                apsWorkDetailListResVo.setCacheTimeValue(phase.getCacheTimeValue());
                apsWorkDetailListResVo.setCacheTimeUnit(phase.getCacheTimeUnit());
            }
        }

        return new BaseListResVo<>(apsWorkDetailListResVos);
    }

    @Transactional
    public BasePageResVo<ApsWorkDetailPubListResVo> pubList(ApsWorkDetailPubListReqVo reqVo) {

        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        wrapper.like(StringUtils.hasText(reqVo.getOrderCode()), "o.order_code", reqVo.getOrderCode());
        wrapper.like(StringUtils.hasText(reqVo.getConstructNo()), "o.construct_no ", reqVo.getConstructNo());
        wrapper.like(StringUtils.hasText(reqVo.getStationCode()), "s.my_code ", reqVo.getStationCode());
        wrapper.like(StringUtils.hasText(reqVo.getStationName()), "s.name ", reqVo.getStationName());
        wrapper.like(StringUtils.hasText(reqVo.getGroupCode()), "g.my_code ", reqVo.getGroupCode());
        wrapper.like(StringUtils.hasText(reqVo.getGroupName()), "g.name ", reqVo.getGroupName());
        wrapper.like(StringUtils.hasText(reqVo.getMaterNo()), "awo.erp_code ", reqVo.getMaterNo());
        wrapper.like(StringUtils.hasText(reqVo.getMaterName()), "awd.mater_name ", reqVo.getMaterName());
        wrapper.ge(reqVo.getPlanStartDateTime() != null, "awd.plan_start_date_time ", reqVo.getPlanStartDateTime());
        wrapper.le(reqVo.getPlanEndDateTime() != null, "awd.plan_end_date_time ", reqVo.getPlanEndDateTime());
        wrapper.eq(reqVo.getTotalCount() != null, "awd.total_count ", reqVo.getTotalCount());
        wrapper.eq(reqVo.getFinishCount() != null, "awd.finish_count ", reqVo.getFinishCount());
        wrapper.like(StringUtils.hasText(reqVo.getPhaseCode()), "awd.phase_code ", reqVo.getPhaseCode());
        wrapper.like(StringUtils.hasText(reqVo.getPhaseName()), "awd.phase_name ", reqVo.getPhaseName());
        wrapper.like(StringUtils.hasText(reqVo.getWorkOrderCode()), "awo.work_order_code ", reqVo.getWorkOrderCode());
        wrapper.like(StringUtils.hasText(reqVo.getPlmId()), "awo.plm_id ", reqVo.getPlmId());
        wrapper.eq(reqVo.getStatus() != null, "awd.status ", reqVo.getStatus());

        wrapper.in("awd.order_type ", 1, 4);
        wrapper.eq("awd.deleted", 0);
        wrapper.ge("awd.status ", 2);


        wrapper.ge(reqVo.getActualStartDateTime() != null, "awd.actual_start_date_time ", reqVo.getActualStartDateTime());
        wrapper.le(reqVo.getActualFinishDateTime() != null, "awd.actual_end_date_time ", reqVo.getActualFinishDateTime());
        wrapper.orderByDesc("awd.plan_start_date_time");
        Page<ApsWorkDetailPubListResVo> page = apsWorkDetailMapper.pubList(reqVo.toPage(), wrapper);
        return BasePageResVo.of(page, ApsWorkDetailPubListResVo.class);
    }

    @Transactional
    public void updateDetailTask(WorkDetailTaskReqVo reqVo) {

        LambdaUpdateChainWrapper<WorkDetailTask> uw = workDetailTaskMapper.lambdaUpdate();
        uw.in(WorkDetailTask::getId, reqVo.getIds());
        uw.set(WorkDetailTask::getGroupCode, reqVo.getGroupCode().trim());
        uw.update();
    }

    @Transactional
    public void detailGroup(WorkDetailTaskReqVo reqVo) {

        Integer count = apsWorkDetailMapper.lambdaQuery()
                .in(ApsWorkDetail::getId, reqVo.getIds())
                .ge(ApsWorkDetail::getStatus, 2)
                .count();
        if (count < 0) {
            throw SyExceptionUtils.e("数据库不存在该数据!");
        }

        // 修改计划
        LambdaUpdateChainWrapper<ApsWorkDetail> uw = apsWorkDetailMapper.lambdaUpdate();
        uw.in(ApsWorkDetail::getId, reqVo.getIds());
        uw.set(ApsWorkDetail::getGroupCode, reqVo.getGroupCode().trim());
        if (reqVo.getPlanStartDateTime() != null) {
            uw.set(ApsWorkDetail::getPlanStartDateTime, reqVo.getPlanStartDateTime());
        }
        if (reqVo.getPlanEndDateTime() != null) {
            uw.set(ApsWorkDetail::getPlanEndDateTime, reqVo.getPlanEndDateTime());
        }
        uw.set(ApsWorkDetail::getAppendFlag, 3);
        uw.set(ApsWorkDetail::getModifyDateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        uw.set(ApsWorkDetail::getModifyUsername, SySecurityUtils.getUserCode());
        uw.update();

        // 修改进行中的任务
        LambdaUpdateChainWrapper<WorkDetailTask> taskWrapper = workDetailTaskMapper.lambdaUpdate();
        taskWrapper.in(WorkDetailTask::getApsWorkDetailId, reqVo.getIds());
        taskWrapper.set(WorkDetailTask::getGroupCode, reqVo.getGroupCode().trim());
        taskWrapper.set(WorkDetailTask::getModifyDateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        taskWrapper.set(WorkDetailTask::getModifyUsername, SySecurityUtils.getUserCode());
        taskWrapper.update();

    }

    public BaseListResVo<AssemPartsCountsResVo> getPartsCount(AssemPartsCountsReqVo reqVo) {
        if (!StringUtils.hasText(reqVo.getAssemblyNumber())) {
            throw SyExceptionUtils.e("父组件编号不能为空");
        }
        if (!StringUtils.hasText(reqVo.getConstructNo())) {
            throw SyExceptionUtils.e("施工号不能为空");
        }
        QueryWrapper<ApsWorkDetail> qw = new QueryWrapper<>();
        qw.lt("awd.STATUS", 4);
        qw.eq("awd.mater_no", reqVo.getAssemblyNumber());
        qw.eq("tor.construct_no", reqVo.getConstructNo());
        List<AssemPartsCountsResVo> list = apsWorkDetailMapper.getPartsCount(qw);
        return BaseListResVo.of(list, AssemPartsCountsResVo.class);
    }

    public BaseListResVo<AssemWorkDetailResVo> dateMesWorkDetail( MesWorkDetailReqVo reqVo) {
        LambdaQueryWrapper<MesWorkDetail> qw = new LambdaQueryWrapper<>();
        if(!CollectionUtils.isEmpty(reqVo.getConstrunctNos())){
            qw.in(MesWorkDetail::getConstructno,reqVo.getConstrunctNos());
        }
        qw.in(MesWorkDetail::getPhaseCode,reqVo.getPhaseCodes());
        qw.eq(MesWorkDetail::getPlanDate, DateUtils.format(new Date(), "yyyy-MM-dd"));
        List<MesWorkDetail> meslist =  mesWorkDetailMapper.selectList(qw);
        List<String>  construnctNos = meslist.stream().map(MesWorkDetail::getConstructno).distinct().collect(Collectors.toList());
        if(CollectionUtils.isEmpty(construnctNos)){
            return BaseListResVo.empty();
        }

        Map<String, List<MesWorkDetail>> mesMap = meslist.stream().collect(Collectors.groupingBy(k ->k.getConstructno() +"_"+ k.getPlmidType() + "_" + k.getPplmid() + "_" + k.getPlmid()+ "_" + k.getPhaseCode() + "_" +k.getShiftNum()));
        if(StringUtils.hasText(reqVo.getPlmid())){
            reqVo.setPlmid(reqVo.getPlmid().trim());
        }
        List<AssemWorkDetailResVo> asselist = workQueueMapper.dateMesWorkDetail(reqVo.getAssermType(),construnctNos,reqVo.getPlmid(),reqVo.getPhaseCodes());
        Map<String, AssemWorkDetailResVo> asseMap = asselist.stream().collect(Collectors.toMap(k ->k.getConstructNo() +"_"+k.getPhaseCode() + "_"+ k.getPlmidType() + "_type" , e->e, (e1, e2)->{
          if(e1.getOneCount()>0&&e2.getOneCount()>0){
              if ((e1.getComTotalQty()/e1.getOneCount())>(e2.getComTotalQty()/e2.getOneCount())) {
                  return e2;
              }
          }

            return e1;
        }));
/*        if(reqVo.getState()!=null&&reqVo.getState()>0){
            List<AssemWorkDetailResVo> filteredList =null;
            if(reqVo.getState()==1){
                filteredList =   asselist.stream()
                        .filter( item -> item.getRemTotalQty()>0)
                        .collect(Collectors.toList());
            }else  if(reqVo.getState()==2){
                filteredList =   asselist.stream()
                        .filter( item -> item.getRemTotalQty()==0)
                        .collect(Collectors.toList());
            }
            asselist=filteredList;
        }*/
        List<AssemWorkDetailResVo> filteredList = asselist.stream()
                .filter(item ->!StringUtils.hasText(reqVo.getChntxt()) || item.getChntxt().contains(reqVo.getChntxt()))
                .filter(item ->!StringUtils.hasText(reqVo.getGroupCode()) || item.getGroupCode().contains(reqVo.getGroupCode()))
                .collect(Collectors.toList());
        asselist=filteredList;
        if(!CollectionUtils.isEmpty(asselist)&& StringUtils.hasText(reqVo.getSort())){
            List<AssemWorkDetailResVo> sortedList=null;
            if(reqVo.getSort().equals("materWeight")){
                if(StringUtils.hasText(reqVo.getOrder())&&reqVo.getOrder().equals("asc")){
                    sortedList = asselist.stream()
                            .sorted(Comparator.comparing(AssemWorkDetailResVo::getMaterWeight))
                            .collect(Collectors.toList());
                }else{
                    sortedList = asselist.stream()
                            .sorted(Comparator.comparing(AssemWorkDetailResVo::getMaterWeight).reversed())
                            .collect(Collectors.toList());
                }
            }else if(reqVo.getSort().equals("remTotalQty")){
                if(StringUtils.hasText(reqVo.getOrder())&&reqVo.getOrder().equals("asc")){
                    sortedList = asselist.stream()
                            .sorted(Comparator.comparing(AssemWorkDetailResVo::getRemTotalQty))
                            .collect(Collectors.toList());

                }else{
                    sortedList = asselist.stream()
                            .sorted(Comparator.comparing(AssemWorkDetailResVo::getRemTotalQty).reversed())
                            .collect(Collectors.toList());
                }
            }
            asselist=sortedList;
        }


        asselist.forEach(e->{
            AssemWorkDetailResVo  vo= asseMap.get(e.getConstructNo() +"_"+e.getPhaseCode() + "_"+e.getPlmidType() + "_type");
            e.setPhaseComQty(vo == null ? 0 : vo.getComTotalQty()/vo.getOneCount());
            e.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));

//            List<MesWorkDetail> mesWorkDetails = mesMap.get(e.getConstructNo() +"_"+ e.getPlmidType() + "_" + e.getPplmId() + "_" + e.getPlmId()+ "_" + e.getPhaseCode());
            List<MesWorkDetail> mesWorkDetails1 = mesMap.get(e.getConstructNo() +"_"+ e.getPlmidType() + "_" + e.getPplmId() + "_" + e.getPlmId()+ "_" + e.getPhaseCode()+ "_" +1);
            List<MesWorkDetail> mesWorkDetails2 = mesMap.get(e.getConstructNo() +"_"+ e.getPlmidType() + "_" + e.getPplmId() + "_" + e.getPlmId()+ "_" + e.getPhaseCode() + "_" +2);
           /* if(!CollectionUtils.isEmpty(mesWorkDetails)){
                e.setPlanUser(mesWorkDetails.stream().map(MesWorkDetail::getPlanUser).distinct().collect(Collectors.joining(", ")));
            }else{
                e.setPlanUser("-");
            }*/
            e.setPlanUser("-");
            if(!CollectionUtils.isEmpty(mesWorkDetails1)){
                e.setCurPlanCount(mesWorkDetails1.stream().mapToInt(MesWorkDetail::getCurPlanCount).max().getAsInt());
                e.setPlan1Qty( mesWorkDetails1.stream().mapToInt(MesWorkDetail::getPlanCount).sum());
                e.setDelayCount(mesWorkDetails1.stream().mapToInt(MesWorkDetail::getDelayCount).sum());
            }else{
                e.setPlan1Qty(0);
            }
            if(!CollectionUtils.isEmpty(mesWorkDetails2)){
                e.setCurPlanCount(mesWorkDetails2.stream().mapToInt(MesWorkDetail::getCurPlanCount).max().getAsInt());
                e.setPlan2Qty( mesWorkDetails2.stream().mapToInt(MesWorkDetail::getPlanCount).sum());
                e.setDelayCount(mesWorkDetails2.stream().mapToInt(MesWorkDetail::getDelayCount).sum());
            }else{
                e.setPlan2Qty(0);
            }
            if(e.getComTotalQty()==null){
              e.setComTotalQty(0);
            }
            e.setCurPlanCount(e.getCurPlanCount()!=null?e.getCurPlanCount():0);
            if(e.getDelayCount()==null||e.getDelayCount()<1){
                int delayCount = e.getCurPlanCount()-e.getPlan1Qty()-e.getPlan2Qty()-e.getComTotalQty();
                e.setDelayCount(Math.max(delayCount, 0));
            }

              if(e.getRemTotalQty()!=null&&e.getRemTotalQty()<0){
               e.setRemTotalQty(0);
              }
            e.setComRate(e.getComTotalQty()==0||e.getCurPlanCount()==0 ?BigDecimal.ZERO
                     : BigDecimal.valueOf(e.getComTotalQty())
                    .divide(BigDecimal.valueOf(e.getCurPlanCount()), 3, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100)));
            if(e.getPerComTotalQty()!=null&&e.getPerComTotalQty()< e.getCurPlanCount()-e.getPlan1Qty()-e.getPlan2Qty()){
                e.setTaskState(3);
            }else if(e.getDelayCount()>0){
                e.setTaskState(1);
            }else if(e.getRemTotalQty()==0){
                e.setTaskState(2);
            }else{
                e.setTaskState(4);
            }
            if(e.getComTotalQty()>0&&e.getCurPlanCount()==0){
                 e.setCurPlanCount(e.getComTotalQty());
            }

        });

         if(reqVo.getState()!=null&&reqVo.getState()>0){
             asselist=asselist.stream().filter(item-> Objects.equals(item.getTaskState(), reqVo.getState())).collect(Collectors.toList());
        }
        return BaseListResVo.of(asselist, AssemWorkDetailResVo.class);
    }

    public WorkDetailGroupResVo getDetailGroup(MesWorkDetailReqVo reqVo) {

        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        wrapper.eq("wd.mater_no", reqVo.getPlmid());
        wrapper.eq("wd.phase_code", reqVo.getPhaseCode());
        wrapper.lt("wd.status", 4);
        wrapper.eq("wd.deleted", 0);
        wrapper.eq("tbo.construct_no", reqVo.getConstrunctNo());
        wrapper.orderByAsc("wd.plan_start_date_time");
        wrapper.last("limit 1");
        ApsWorkDetail  apsWorkDetail = apsWorkDetailMapper.selectByOrder(wrapper);
        WorkDetailGroupResVo  vo=new WorkDetailGroupResVo();
        if(!ObjectUtils.isEmpty(apsWorkDetail)){
            Group one = groupMapper.lambdaQuery().eq(Group::getId, apsWorkDetail.getGroupId()).one();
            vo.setGroupId(apsWorkDetail.getGroupId());
            vo.setGroupName(one.getName());
        }
        List<Group> phaseList = groupMapper.selectGroupByPhase(reqVo.getPhaseCode());
       vo.setPhaseGroups(phaseList);
        return vo;
    }

    public BaseResVo updateDetailGroup(MesWorkDetailReqVo reqVo) {
        QueryWrapper<ApsWorkDetail> wrapper = Wrappers.query();
        wrapper.eq("tbo.construct_no", reqVo.getConstrunctNo());
        wrapper.eq("wd.mater_no", reqVo.getPlmid());
        wrapper.eq("wd.phase_code", reqVo.getPhaseCode());
        wrapper.lt("wd.status", 4);
        wrapper.eq("wd.deleted", 0);
        List<ApsWorkDetail> apsWorkDetails = apsWorkDetailMapper.selectDetailByOrder(wrapper);
        Group group = groupMapper.lambdaQuery().eq(Group::getMyCode,reqVo.getGroupCode()).one();
       if(!CollectionUtils.isEmpty(apsWorkDetails)){
           // 修改计划
           LambdaUpdateChainWrapper<ApsWorkDetail> uw = apsWorkDetailMapper.lambdaUpdate();
           uw.in(ApsWorkDetail::getId, apsWorkDetails.stream().map(ApsWorkDetail::getId).collect(Collectors.toList()));
           uw.set(ApsWorkDetail::getGroupId, group.getId());
           uw.set(ApsWorkDetail::getGroupCode, reqVo.getGroupCode().trim());
           uw.set(ApsWorkDetail::getModifyDateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
           uw.set(ApsWorkDetail::getModifyUsername, SySecurityUtils.getUserCode());
           uw.update();

           // 修改进行中的任务
           LambdaUpdateChainWrapper<WorkDetailTask> taskWrapper = workDetailTaskMapper.lambdaUpdate();
           taskWrapper.in(WorkDetailTask::getApsWorkDetailId, apsWorkDetails.stream().map(ApsWorkDetail::getId).collect(Collectors.toList()));
           taskWrapper.set(WorkDetailTask::getGroupCode, reqVo.getGroupCode().trim());
           taskWrapper.set(WorkDetailTask::getModifyDateTime, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
           taskWrapper.set(WorkDetailTask::getModifyUsername, SySecurityUtils.getUserCode());
           taskWrapper.update();

           mesWorkDetailMapper.lambdaUpdate().eq(MesWorkDetail::getConstructno, reqVo.getConstrunctNo()).eq(MesWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                   .eq(MesWorkDetail::getPlmid,  reqVo.getPlmid()).eq(MesWorkDetail::getPlanDate,  DateUtils.format(new Date(), "yyyy-MM-dd"))
                   .set(MesWorkDetail::getGroupId, group.getId()).update();

       }

        return  BaseResVo.ok();
    }

    public BaseResVo createWorkDetail(AssemWorkShiftReqVO reqVo) {
        if(CollectionUtils.isEmpty(reqVo.getMesWorkDetailReqVo())){
            return BaseResVo.fail("当前工单明细不能等于空！");
        }
        if(!reqVo.getMesWorkDetailReqVo().isEmpty()){
            AssemWorkDetailReqVo assemWorkDetailReqVo = reqVo.getMesWorkDetailReqVo().get(0);
            LambdaQueryWrapper<MesWorkDetail> eq = Wrappers.<MesWorkDetail>lambdaQuery().eq(MesWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                    .eq(MesWorkDetail::getPlmidType, assemWorkDetailReqVo.getPlmidType()).eq(MesWorkDetail::getConstructno, assemWorkDetailReqVo.getConstructNo())
                    .eq(MesWorkDetail::getShiftNum, reqVo.getShiftNum())
                    .eq(MesWorkDetail::getPlanDate, DateUtils.format(new Date(), "yyyy-MM-dd"));
            mesWorkDetailMapper.delete(eq);
            for (AssemWorkDetailReqVo e : reqVo.getMesWorkDetailReqVo()) {
                MesWorkDetail md = new MesWorkDetail();
                BeanUtils.copyProperties(e, md);
                int count = reqVo.getMatchCount()*e.getOneCount() - e.getComTotalQty();
                if(count>0){
                    md.setPlanCount(count );
                    md.setShiftNum(reqVo.getShiftNum());
                    md.setConstructno(e.getConstructNo());
                    md.setGroupId(e.getGroupId());
                    md.setAssertName(e.getPartAlisName());
                    md.setPlmid(e.getPlmId());
                    md.setPplmid(e.getPplmId());
                    md.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));
                    md.setPlanUser(SySecurityUtils.getUserCode());
                    md.setPhaseCode(reqVo.getPhaseCode());
                    mesWorkDetailMapper.insert(md);
                }

            }
        }


        return  BaseResVo.ok();
    }

    public BaseResVo updateWorkDetail(AssemUpdateWorkShiftReqVO reqVo) {
        if (!ObjectUtils.isEmpty(reqVo.getMesWorkDetailReqVo())) {
            AssemWorkDetailReqVo   e= reqVo.getMesWorkDetailReqVo();
            MesWorkDetail one = mesWorkDetailMapper.lambdaQuery().eq(MesWorkDetail::getPplmid, e.getPplmId())
                    .eq(MesWorkDetail::getPlmid, e.getPlmId()).eq(MesWorkDetail::getPlmidType, e.getPlmidType())
                    .eq(MesWorkDetail::getConstructno, e.getConstructNo()).eq(MesWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                    .eq(MesWorkDetail::getPlanDate, DateUtils.format(new Date(), "yyyy-MM-dd"))
                    .eq(MesWorkDetail::getShiftNum, 1).last("limit 1").one();
            if(ObjectUtils.isEmpty(one)){
                MesWorkDetail md = new MesWorkDetail();
                BeanUtils.copyProperties(e, md);
                md.setPlanCount(reqVo.getPlan1Qty());
                md.setShiftNum(1);
                md.setGroupId(e.getGroupId());
                md.setConstructno(e.getConstructNo());
                md.setAssertName(e.getPartAlisName());
                md.setPlmid(e.getPlmId());
                md.setPplmid(e.getPplmId());
                md.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));
                md.setPlanUser(SySecurityUtils.getUserCode());
                md.setPhaseCode(reqVo.getPhaseCode());
                mesWorkDetailMapper.insert(md);
            }else{
                one.setPlanCount(reqVo.getPlan1Qty());
                mesWorkDetailMapper.updateById(one);
            }
            //.set(MesWorkDetail::getPlanCount, reqVo.getPlan1Qty()).update();
            MesWorkDetail two = mesWorkDetailMapper.lambdaQuery().eq(MesWorkDetail::getPplmid, e.getPplmId())
                    .eq(MesWorkDetail::getPlmid, e.getPlmId()).eq(MesWorkDetail::getPlmidType, e.getPlmidType())
                    .eq(MesWorkDetail::getPlanDate, DateUtils.format(new Date(), "yyyy-MM-dd"))
                    .eq(MesWorkDetail::getConstructno, e.getConstructNo()).eq(MesWorkDetail::getPhaseCode, reqVo.getPhaseCode())
                    .eq(MesWorkDetail::getShiftNum, 2).last("limit 1").one();
            if(ObjectUtils.isEmpty(two)){
                MesWorkDetail md = new MesWorkDetail();
                BeanUtils.copyProperties(e, md);
                md.setPlanCount(reqVo.getPlan2Qty());
                md.setShiftNum(2);
                md.setGroupId(e.getGroupId());
                md.setConstructno(e.getConstructNo());
                md.setAssertName(e.getPartAlisName());
                md.setPlmid(e.getPlmId());
                md.setPplmid(e.getPplmId());
                md.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));
                md.setPlanUser(SySecurityUtils.getUserCode());
                md.setPhaseCode(reqVo.getPhaseCode());
                mesWorkDetailMapper.insert(md);
            }else{
                two.setPlanCount(reqVo.getPlan2Qty());
                mesWorkDetailMapper.updateById(two);
            }
//                    .set(MesWorkDetail::getPlanCount, reqVo.getPlan2Qty()).update();
        }
        return  BaseResVo.ok();
    }



    public Result<List<PdaWorkDetailResVo>> pdaDateMesWorkDetail(String stationCode, Integer shiftNum) {
        Group group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", stationCode));
        if (ObjectUtils.isEmpty(group)) {
            group = groupMapper.selectGroupByWorkPlace(Wrappers.<Group>query()
                    .eq("ts.my_code",stationCode));
        }
        if(ObjectUtils.isEmpty(group)){
            throw new RuntimeException("未找到" + stationCode + "对应的工作组");
        }
//        PhaseGroup one = phaseGroupMapper.lambdaQuery().eq(PhaseGroup::getGroupCode, group.getMyCode()).one();
/*       if(ObjectUtils.isEmpty(one)){
           throw new RuntimeException("未找到"+stationCode+"该工位对应的工序");
       }*/

        List<PdaWorkDetailResVo>  list=new LinkedList<>();
        QueryWrapper<MesWorkDetail> qw = new QueryWrapper<>();
        qw.eq("mwd.plan_date", DateUtils.format(new Date(), "yyyy-MM-dd"));
//        qw.eq("mwd.phase_code", one.getPhaseCode());
        qw.eq("mwd.group_id", group.getId());
        String startTime = " 06:00:00";
        String endTime = " 18:00:00";
        String startTime2 = " 06:00:00";
        if(shiftNum>0){
            qw.eq("mwd.shift_num", shiftNum);
            qw.groupBy("mwd.constructno,mwd.plmid,mwd.shift_num,mwd.phase_code,mwd.part_name,mwd.op_size_note,mwd.delay_count ,mwd.plan_start_time , mwd.plan_end_time ,mwd.mater_weight");
            if(shiftNum==1){
                startTime=DateUtils.format(new Date(), "yyyy-MM-dd")+startTime;
                endTime=DateUtils.format(new Date(), "yyyy-MM-dd")+endTime;
            }else{
                startTime=DateUtils.format(new Date(), "yyyy-MM-dd")+endTime;
                endTime=DateUtils.format(LocalDateTime.now().plusDays(1), "yyyy-MM-dd")+startTime2;
            }
            list =  mesWorkDetailMapper.pdaDateMesWorkDetail(startTime,endTime,qw);
        }else {
            startTime=DateUtils.format(new Date(), "yyyy-MM-dd")+startTime;
            endTime=DateUtils.format(new Date(), "yyyy-MM-dd")+endTime;
            qw.eq("mwd.shift_num", 1);
            qw.groupBy("mwd.constructno,mwd.plmid,mwd.shift_num,mwd.phase_code,mwd.part_name,mwd.delay_count ,mwd.plan_start_time , mwd.plan_end_time ,mwd.op_size_note,mwd.mater_weight");
            list =  mesWorkDetailMapper.pdaDateMesWorkDetail(startTime,endTime,qw);
            qw = new QueryWrapper<>();
            qw.eq("mwd.shift_num", 2);
            qw.eq("mwd.group_id", group.getId());
            qw.eq("mwd.plan_date", DateUtils.format(new Date(), "yyyy-MM-dd"));
            startTime2 = DateUtils.format(LocalDateTime.now().plusDays(1), "yyyy-MM-dd")+" 06:00:00";
            qw.groupBy("mwd.constructno,mwd.plmid,mwd.shift_num,mwd.phase_code,mwd.part_name,mwd.delay_count ,mwd.plan_start_time , mwd.plan_end_time ,mwd.op_size_note,mwd.mater_weight");
            List<PdaWorkDetailResVo>  list2 =  mesWorkDetailMapper.pdaDateMesWorkDetail(endTime,startTime2,qw);
            list.addAll(list2);
        }
        if(!CollectionUtils.isEmpty(list)){
            List<String> plimids = list.stream().map(k -> k.getPlmid()).distinct().collect(Collectors.toList());
            List<String> phaseCodes = list.stream().map(k -> k.getPhaseCode()).distinct().collect(Collectors.toList());
            List<PartPallet> partPalletList = partPalletMapper.lambdaQuery()
                    .in(PartPallet::getPlmId,plimids)
                    .in(PartPallet::getPhaseCode, phaseCodes)
                    .list();
            Map<String, List<PartPallet>> partMap = partPalletList.stream().collect(Collectors.groupingBy(k->k.getPlmId()+"_"+k.getPhaseCode(), Collectors.toList()));
            list.forEach(k->{
                if(partMap.containsKey(k.getPlmid()+"_"+k.getPhaseCode())){
                    List<PartPallet>  pp= partMap.get(k.getPlmid()+"_"+k.getPhaseCode());
                    for (PartPallet partPallet : pp){
                        WorkDetailPartPlateResVo  pplates=new WorkDetailPartPlateResVo();
                        pplates.setPlmid(partPallet.getPlmId());
                        pplates.setPhaseCode(partPallet.getPhaseCode());
                        pplates.setLoadingCode(partPallet.getLoadingCode());
                        pplates.setPositionCode(partPallet.getPositionCode());
                        pplates.setPartCount(partPallet.getPartCount());
                        k.getPplates().add(pplates);
                    }

                }
            });
        }

        return Result.success(list);
    }

    public BaseResVo makeMesWorkDetail(String date) {
        if(!StringUtils.hasText( date)){
            date=DateUtils.format(new Date(), "yyyy-MM-dd");
        }
        String startTime = " 06:00:00";
        String endTime = " 18:00:00";
        List<AssemWorkDetailResVo> asselist = Optional.ofNullable(workQueueMapper.workDetailPlane( LocalDate.parse( date).minusMonths(1) + startTime, date + endTime))
                .orElseGet(Collections::emptyList)  // 如果返回 null，替换成空列表
                .stream().filter(k -> k.getRemTotalQty() > 0)
                .collect(Collectors.toList());

        List<AssemWorkDetailResVo> asselistBlack =Optional.ofNullable( workQueueMapper.workDetailPlane(date+endTime, LocalDate.parse( date).plusDays(1) +startTime))
                .orElseGet(Collections::emptyList)
                .stream().filter(k -> k.getRemTotalQty() > 0).collect(Collectors.toList());
        Map<String, List<AssemWorkDetailResVo>> mapDay = asselist.stream().collect(Collectors.groupingBy(k ->k.getConstructNo()+"_"+ k.getPplmId() + "_" + k.getPlmId() + "_"+ k.getPhaseCode() + "_" +k.getGroupId() + "_" + 1));
        Map<String, List<AssemWorkDetailResVo>> mapBlack = asselistBlack.stream().collect(Collectors.groupingBy(k ->k.getConstructNo()+"_"+ k.getPplmId() + "_" + k.getPlmId()+ "_"+ k.getPhaseCode()  + "_" +k.getGroupId() + "_" + 2));
        Set<String >  constructNos=asselist.stream().map(AssemWorkDetailResVo::getConstructNo).collect(Collectors.toSet());
        Set<String> constructNosBlack = asselistBlack.stream().map(AssemWorkDetailResVo::getConstructNo).collect(Collectors.toSet());
        constructNosBlack.addAll(constructNos);
        // 直接进行清场
        mesWorkDetailMapper.delete(Wrappers.<MesWorkDetail>lambdaQuery().eq(MesWorkDetail::getPlanDate,date));
        for (String constructNo : constructNosBlack) {

            List<MesWorkDetail> mesDeatil = new ArrayList<>();
            List<AssemWorkDetailResVo> curlAsselist= workQueueMapper.curleWorkDetail(constructNo,LocalDate.parse( date).plusDays(1) +startTime);
            for (AssemWorkDetailResVo e : curlAsselist) {
                if(e.getPlanTotalQty()==null){
                  e.setPlanTotalQty(0);
                }
                List<AssemWorkDetailResVo> dataList =  mapDay.get(constructNo+"_"+ e.getPplmId() + "_" + e.getPlmId() + "_"+ e.getPhaseCode()+ "_" +e.getGroupId()  + "_" + 1);
                List<AssemWorkDetailResVo> dataBackList =  mapBlack.get(constructNo+"_"+ e.getPplmId() + "_" + e.getPlmId() + "_"+ e.getPhaseCode()+ "_" +e.getGroupId()  + "_" + 2);
                int count =CollectionUtils.isEmpty(dataList)?0: dataList.stream().mapToInt(AssemWorkDetailResVo::getPlanTotalQty).sum();
                int blackCount =CollectionUtils.isEmpty(dataBackList)?0:  dataBackList.stream().mapToInt(AssemWorkDetailResVo::getPlanTotalQty).sum();


                if(!CollectionUtils.isEmpty(dataList)){
                    MesWorkDetail md = new MesWorkDetail();
                    BeanUtils.copyProperties(e, md);
                    md.setConstructno(constructNo);
                    md.setPlanStartTime(dataList.get(0).getPlanStartTime());
                    md.setPlanEndTime(dataList.get(0).getPlanEndTime());
                    md.setPplmid(e.getPplmId());


                    if(LocalDateTime.parse(md.getPlanStartTime(),DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")).isBefore(LocalDateTime.now())){
                        // 延期的或  直接算延期数量
                        int dalay =CollectionUtils.isEmpty(dataList)?0: dataList.stream().mapToInt(AssemWorkDetailResVo::getRemTotalQty).sum();
                         md.setDelayCount(dalay);
                        md.setPlanCount(dalay);
                        md.setDayCount(dalay);
                        md.setCurPlanCount(count);
                    }else{
                        int planeCount=e.getPlanTotalQty()-count-blackCount;//  前天计划的数量
                        md.setDelayCount(Math.max(planeCount - e.getComTotalQty(), 0));
                        md.setPlanCount(count);
                        md.setDayCount(count+blackCount);
                        md.setCurPlanCount(e.getPlanTotalQty());
                    }
                    md.setPhaseCode(e.getPhaseCode());
                    md.setPlmid(e.getPlmId());
                    md.setAssertName(e.getPartAlisName());
                    md.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));
                    md.setShiftNum(1);

                    mesDeatil.add(md);

                }
                if(!CollectionUtils.isEmpty(dataBackList)){
                    int planeCount=e.getPlanTotalQty()-count-blackCount;//  前天计划的数量
                    MesWorkDetail md = new MesWorkDetail();
                    BeanUtils.copyProperties(e, md);
                    md.setPlanStartTime(dataBackList.get(0).getPlanStartTime());
                    md.setPlanEndTime(dataBackList.get(0).getPlanEndTime());
                    md.setConstructno(constructNo);
                    md.setPhaseCode(e.getPhaseCode());
                    md.setPplmid(e.getPplmId());
                    md.setPlmid(e.getPlmId());
                    md.setDelayCount(Math.max(planeCount - e.getComTotalQty(), 0));
                    md.setAssertName(e.getPartAlisName());
                    md.setPlanDate(DateUtils.format(new Date(), "yyyy-MM-dd"));
                    md.setShiftNum(2);
                    md.setPlanCount(blackCount);
                    md.setDayCount(count+blackCount);
                    md.setCurPlanCount(e.getPlanTotalQty());
                    mesDeatil.add(md);
                }
            }
            mesWorkDetailMapper.insertBatch(mesDeatil);
        }

        return BaseResVo.ok();
    }

    public Result<Integer> getDetailCount(MesWorkDetailCountReqVo reqVo) {

        String startTime = " 06:00:00";
        reqVo.setDetailDate(reqVo.getDetailDate()+startTime);
        AssemWorkDetailResVo asselist = workQueueMapper.getDetailCount(reqVo);
        if(Objects.nonNull(asselist)){
            return Result.success(asselist.getPlanTotalQty()) ;
        }else{
            return Result.success(0);
        }
    }

    public Result<List<String>> construnctNoList() {
        LambdaQueryWrapper<MesWorkDetail> qw = new LambdaQueryWrapper<>();
        qw.eq(MesWorkDetail::getPlanDate, DateUtils.format(new Date(), "yyyy-MM-dd"));
        List<MesWorkDetail> meslist =  mesWorkDetailMapper.selectList(qw);
        List<String>  construnctNos = meslist.stream().map(MesWorkDetail::getConstructno).distinct().collect(Collectors.toList());
        return Result.success("当日订单列表",construnctNos);
    }

    @SneakyThrows
    @Transactional(readOnly = true)
    public Result<List<PdaWorkDetailResVo>> pdaDateMesWorkDetailMk(String stationCode, Integer shiftNum) {
        Group group = groupMapper.selectOne(new QueryWrapper<Group>().eq("my_code", stationCode));
        if (ObjectUtils.isEmpty(group)) {
            group = groupMapper.selectGroupByWorkPlace(Wrappers.<Group>query()
                    .eq("ts.my_code", stationCode));
        }
        if (ObjectUtils.isEmpty(group)) {
            throw new RuntimeException("未找到" + stationCode + "对应的工作组");
        }

        String groupCode = group.getMyCode();
        LocalDate currentDate = LocalDate.now();
        String currentDateStr = currentDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String start = currentDateStr + " 07:00:00";
        String end = currentDate.plusDays(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")) + " 07:00:00";

        // 动态计划
        List<TomorrowScheduleListVo> adoList = adoWorkDetailMapper.findAdoTomorrowSchedule(groupCode, start, end);
        for (TomorrowScheduleListVo tomorrowScheduleListVo : adoList) {
            tomorrowScheduleListVo.setFinishCount(0);
        }

        List<Integer> orderIdList = adoList.stream().map(TomorrowScheduleListVo::getOrderId).distinct().collect(Collectors.toList());

        // 静态计划
        List<TomorrowScheduleListVo> list = apsWorkDetailMapper.getTomorrowSchedule(groupCode, start, end);

        // 如果有动态计划，就把静态计划移除
        if (CollUtil.isNotEmpty(orderIdList)) {
            list.removeIf(e -> orderIdList.contains(e.getOrderId()));
            list.addAll(adoList);
        }

        Map<String, TomorrowScheduleListVo> collect = list.stream()
                .collect(Collectors.toMap(e -> e.getConstruNum() + "_" + e.getPartNo(), e -> e, (k, v) -> {
                    if(k.getPlanStartDate().compareTo(v.getPlanStartDate()) > 0){
                        k.setPlanStartDate(v.getPlanStartDate());
                    }
                    k.setPlanJobCount(k.getPlanJobCount() + v.getPlanJobCount());
                    k.setFinishCount(k.getFinishCount() + v.getFinishCount());
                    return k;
                }));
        List<TomorrowScheduleListVo> ll = new ArrayList<>(collect.values());
        ll.sort(Comparator.comparing(TomorrowScheduleListVo::getPlanStartDate));

//        String shiftName = now.isBefore(mid)?"白班":"夜班";
        String startStr = start;
        String endStr = end;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date startDate = simpleDateFormat.parse(startStr);
        Date endDate = simpleDateFormat.parse(endStr);

//        List<TomorrowScheduleListVo> finishList = syTyMapper.findFinish(tomorrowScheduleListDto.getWorkPlaceName().trim(), now.isBefore(mid) ? start : midStr, now.isBefore(mid) ? midStr : end, ServletUtils.getHeadParameter("worker"));
        List<TomorrowScheduleListVo> finishList = workDetailTaskMapper.findFinish(groupCode, startStr, endStr);
        Map<Integer, Map<String, TomorrowScheduleListVo>> collect1 = finishList.stream().collect(Collectors.groupingBy(TomorrowScheduleListVo::getOrderId, Collectors.toMap(TomorrowScheduleListVo::getPartNo, e -> e)));


        // 昨天
        LocalDate yesterDay = LocalDate.parse(currentDateStr, DatePattern.NORM_DATE_FORMATTER).minusDays(1);
        String yesterdayStart = yesterDay + " 07:00:00";
        String yesterdayEnd = yesterDay.plusDays(1) + " 07:00:00";
        List<TomorrowScheduleListVo> adoYesterDayList = adoWorkDetailMapper.findAdoTomorrowSchedule(groupCode, yesterdayStart, yesterdayEnd);
        for (TomorrowScheduleListVo vo : adoYesterDayList) {
            vo.setFinishCount(0);
        }
        Map<Integer, Map<String, TomorrowScheduleListVo>> yesterDayMap = adoYesterDayList.stream().collect(Collectors.groupingBy(TomorrowScheduleListVo::getOrderId, Collectors.toMap(TomorrowScheduleListVo::getPartNo, e -> e, (e1, e2) -> {
            e1.setPlanJobCount(e1.getPlanJobCount() + e2.getPlanJobCount());
            e2.setFinishCount(e2.getFinishCount() + e1.getFinishCount());
            return e1;
        })));

        // 明天
        LocalDate tomorrowDay = LocalDate.parse(currentDateStr, DatePattern.NORM_DATE_FORMATTER).plusDays(1);
        String tomorrowStart = tomorrowDay + " 07:00:00";
        String tomorrowEnd = tomorrowDay.plusDays(1) + " 07:00:00";
        List<TomorrowScheduleListVo> adoTomorrowDayList = adoWorkDetailMapper.findAdoTomorrowSchedule(groupCode, tomorrowStart, tomorrowEnd);
        for (TomorrowScheduleListVo vo : adoTomorrowDayList) {
            vo.setFinishCount(0);
        }
        Map<Integer, Map<String, TomorrowScheduleListVo>> tomorrowMap = adoTomorrowDayList.stream().collect(Collectors.groupingBy(TomorrowScheduleListVo::getOrderId, Collectors.toMap(TomorrowScheduleListVo::getPartNo, e -> e, (e1, e2) -> {
            e1.setPlanJobCount(e1.getPlanJobCount() + e2.getPlanJobCount());
            e2.setFinishCount(e2.getFinishCount() + e1.getFinishCount());
            return e1;
        })));

        for (TomorrowScheduleListVo vo : ll) {

            TomorrowScheduleListVo a = collect1.getOrDefault(vo.getOrderId(), new HashMap<>()).get(vo.getPartNo());
            if(a == null){
                vo.setFinishCount(0);
            } else {
                vo.setFinishCount(a.getFinishCount());
            }

            TomorrowScheduleListVo yesterday = yesterDayMap.getOrDefault(vo.getOrderId(), new HashMap<>()).get(vo.getPartNo());
            TomorrowScheduleListVo tomorrow = tomorrowMap.getOrDefault(vo.getOrderId(), new HashMap<>()).get(vo.getPartNo());
            if(shiftNum > 0){
                if(yesterday == null && tomorrow != null && vo.getPlanJobCount() <= (tomorrow.getPlanJobCount() / 2 + 1)){
                    if (shiftNum.equals(1)) {
                        vo.setPlanJobCount(0);
                    }
                } else if (tomorrow == null && yesterday != null && vo.getPlanJobCount() <= (yesterday.getPlanJobCount() / 2 + 1) ){
                    if (shiftNum.equals(2)) {
                        vo.setPlanJobCount(0);
                    }
                } else {
                    int mod = vo.getPlanJobCount() % 2;
                    // 判断当前是否为12点之前
                    if (shiftNum.equals(1)) {
                        vo.setPlanJobCount((vo.getPlanJobCount() / 2) + mod);
                    } else {
                        vo.setPlanJobCount(vo.getPlanJobCount() / 2);
                    }
                }
            }




            if (vo.getPlanJobCount() == 0) {
                vo.setFinishRate(BigDecimal.ZERO);
            } else {
                BigDecimal multiply = new BigDecimal(vo.getFinishCount()).divide(new BigDecimal(vo.getPlanJobCount()), 2, RoundingMode.HALF_UP).multiply(new BigDecimal(100));
                vo.setFinishRate(multiply);
            }
            vo.setPlanStartDate(startDate);
            vo.setEndDate(endDate);
            vo.setDueDate(endDate);

        }

        String finalStart = start;
        String finalEnd = end;
        String finalMid = currentDateStr + " 19:00:00";

        List<PdaWorkDetailResVo> collect2 = ll.stream()
                .sorted(Comparator.comparing(e->e.getPlanStartDate()))
                .map(e -> {
                    PdaWorkDetailResVo vo = new PdaWorkDetailResVo();

                    vo.setOrderId(e.getOrderId());
                    vo.setPlmid(e.getPartNo());
                    vo.setPartName(e.getPartName());
                    vo.setMaterWeight(BigDecimal.ZERO);
                    vo.setConstructno(e.getConstruNum());
                    vo.setPhaseCode("");
                    vo.setOpSizeNote("");
                    vo.setDelayCount(0);
                    vo.setPlanStartTime(finalStart);
                    vo.setPlanEndTime(finalEnd);
                    if (shiftNum.equals(1)) {
                        vo.setPlanEndTime(finalMid);
                    } else if (shiftNum.equals(2)){
                        vo.setPlanStartTime(finalStart);
                    }
                    vo.setPlanTotalQty(e.getPlanJobCount());
                    vo.setComTotalQty(e.getFinishCount());

                    vo.setShiftNum(shiftNum);
                    return vo;
                })
                .collect(Collectors.toList());


        if (CollUtil.isNotEmpty(collect2)) {
            List<OrderPart> orderPartList = orderPartMapper.lambdaQuery()
                    .in(OrderPart::getPlmId, collect2.stream().map(PdaWorkDetailResVo::getPlmid).collect(Collectors.toList()))
//                    .eq(OrderPart::getMaterType, "Platepart")
//                    .isNotNull(OrderPart::getPngUrl)
                    .list();
            Map<String, List<OrderPart>> orderPartMap = orderPartList.stream().collect(Collectors.groupingBy(OrderPart::getPlmId));

            collect2.forEach(e->{
                List<OrderPart> orderParts = orderPartMap.get(e.getPlmid());
                if (CollUtil.isNotEmpty(orderParts)) {
                    OrderPart orderPart = orderParts.get(0);
                    if (StringUtils.hasText(orderPart.getPngUrl())) {
                        e.setPartUrl("http://172.31.3.109:8090" + String.format(projectConfig.getUrlPre(), e.getPlmid(), orderPart.getPngUrl()));
                    }
                    e.setMaterWeight(orderPart.getNestWeight() != null ? orderPart.getNestWeight() : orderPart.getNetWeight());
                    if (orderPart.getLength()!=null&&orderPart.getWidth()!=null) {
                        e.setOpSizeNote(orderPart.getLength().setScale(0, RoundingMode.HALF_UP) + "*" + orderPart.getWidth().setScale(0, RoundingMode.HALF_UP) + "*" + orderPart.getThickness().setScale(0, RoundingMode.HALF_UP));
                    }
                }
            });

            List<PdaWorkDetailResVo> listVos = collect2.stream().filter(e -> !StringUtils.hasText(e.getPartUrl())).collect(Collectors.toList());
            if (CollUtil.isNotEmpty(listVos)) {
                List<String> partNos = listVos.stream().map(e -> {
                    if (e.getPlmid().endsWith("_170")) {
                        return e.getPlmid().substring(0, e.getPlmid().indexOf("_170"));
                    } else {
                        return e.getPlmid();
                    }
                }).distinct().collect(Collectors.toList());
                Map<String, String> pdfMap = new HashMap<>();
                for (String partNo : partNos) {
                    // 工序图
                    String drawingUrl = mbdFeign.getProcessDrawingUrl(partNo);
                    if (!StringUtils.hasText(drawingUrl)) {
                        drawingUrl = mbdFeign.getDesignDrawingUrl(partNo, partNo);
                    }
                    if (StringUtils.hasText(drawingUrl)) {
                        pdfMap.put(partNo, drawingUrl);
                        pdfMap.put(partNo + "_170", drawingUrl);
                    }
                }
                for (PdaWorkDetailResVo vo : collect2) {
                    if (!StringUtils.hasText(vo.getPartUrl())) {
                        String pdf = pdfMap.get(vo.getPlmid());
                        if (StringUtils.hasText(pdf)) {
                            vo.setPartUrl(pdf);
                        }
                    }
                }
            }

            List<PdaWorkDetailResVo> collect4 = collect2.stream().filter(e -> !StringUtils.hasText(e.getOpSizeNote())).collect(Collectors.toList());
            Set<String> collect3 = collect4.stream().map(PdaWorkDetailResVo::getPlmid).collect(Collectors.toSet());
            if (CollUtil.isNotEmpty(collect3)) {
                Map<String, AssemblyInfo> sizeInfo = mbdFeign.getSizeInfo(collect3);
                for (PdaWorkDetailResVo pdaWorkDetailResVo : collect4) {
                    AssemblyInfo assemblyInfo = sizeInfo.get(pdaWorkDetailResVo.getPlmid());
                    if (assemblyInfo != null) {
                        pdaWorkDetailResVo.setOpSizeNote(new BigDecimal(StringUtils.hasText(assemblyInfo.getLength())? assemblyInfo.getLength() : "0").setScale(0, RoundingMode.HALF_UP) + "*" + new BigDecimal(StringUtils.hasText(assemblyInfo.getWidth())? assemblyInfo.getWidth() : "0").setScale(0, RoundingMode.HALF_UP) + "*" + new BigDecimal(StringUtils.hasText(assemblyInfo.getThickness())? assemblyInfo.getThickness() : "0").setScale(0, RoundingMode.HALF_UP));
                    }
                }
            }
        }

        collect2.sort((o1, o2) -> {
            if (o1.getComTotalQty() < o1.getPlanTotalQty() && o2.getComTotalQty() < o2.getPlanTotalQty()) {
                return o1.getPlanStartTime().compareTo(o2.getPlanStartTime());
            }

            if (o1.getComTotalQty() >= o1.getPlanTotalQty() && o2.getComTotalQty() >= o2.getPlanTotalQty()) {
                return o1.getPlanStartTime().compareTo(o2.getPlanStartTime());
            }

            if (o1.getComTotalQty() >= o1.getPlanTotalQty()) {
                return 1;
            }
            return -1;

        });
        for (PdaWorkDetailResVo vo : collect2) {
            vo.setPlanStartTime(startStr);
        }

        collect2.removeIf(e->e.getPlanTotalQty()<=0);
        return Result.success(collect2);
    }
}
